import web, os, sys
web.config.debug = False # will not work with sessions
import ConfigParser # for working directory specific settings        
import hashlib # this is useful to encrypt hashes in password validation and storage


config = ConfigParser.RawConfigParser()
# todo: find a reliable way of reading files from a central directory
config.read('/home/neorou73/webapps/cars_app/htdocs/config.cfg')


topUrl = config.get('app_settings', 'topUrl')
sessionsDir = config.get('app_settings', 'sessionsDir')
appDb = config.get('app_settings', 'appDb')
runMethod = config.get('app_settings', 'runMethod')


urls = (
    '/', 'hello',
    '/home', 'hello',
    '/cars','cars',
    '/cars/gas/purchase','gasPurchase',
    '/environment.*', 'environment',
    '/help', 'help',
    '/login', 'login',
    '/logout', 'logout'
    )
                                                                   

htmlStarter = """
<!DOCTYPE html>
<html>
  <head>
    <title>Gimme Gas</title>
    <style type='text/css' rel='stylesheet'>
    body, p, td, th, input {
      font-family: sans-serif;
      font-size: 18pt;
    }
    table.lined th, table.lined td {
      border: solid 0.1em black;
    }
    th {
      text-align: right;
    }
    </style>
  </head>
  <body>
"""

htmlMainNav = """
    <div id='main-nav'>
      <ul>
        <li><a href='/app/cars'>cars</a></li>
        <li><a href='/app/cars/gas/purchase'>record gas purchase</a></li>
        <li><a href='/app/logout'>logout</a></li>
      </ul>  
    </div>
"""  


htmlEnder = """
  </body>
</html>
"""

# define the app variable so the session can use it
app = web.application(urls, globals())

# define the session parameters
if web.config.get('_session') is None:                         
    session = web.session.Session(app, web.session.DiskStore(sessionsDir), initializer={'username': '', 'password': ''})
    web.config._session = session
else:
    session = web.config._session


class hello:
    def GET(self):
        if not session.username:
            raise web.seeother('/app/login')
        else:
            html = htmlStarter + htmlMainNav + session.username + '<p><a href="/app/logout">not ' + session.username + '?</a></p>' + htmlEnder
            return html
        
class login:
    def GET(self):
        """
        designed to return user data if session.username and session.udi set
        otherwise print a simple login screen
        this should always return for itself
        """
        html = htmlStarter + """
    <form method='post' id='login-form'>
      <table>
        <tr>
          <th>user:</th>
          <td><input name='u' size='25' /></td>
        </tr>
        <tr>
          <th>password:</th>
          <td><input type='password' name='p' size='25' /></td>
        </tr>
        <tr>
          <td colspan=2><input type='submit' value='login' /></td>
        </tr>
      </table>  
    </form>
""" + htmlEnder        
        return html

    def POST(self):
        post_input = web.input()
        # test the output for debugging
        # return 'user: ' + post_input.u + '; password: ' + post_input.p     
        db = web.database(dbn='sqlite', db=appDb)
        
        m = hashlib.md5()
        m.update(post_input.p)
        pwencr = m.hexdigest()
        uservar = dict(username=post_input.u, password=pwencr)
        validUser = db.select('users', uservar, where="username = $username and password = $password")
        # otherwise if successful return to home page
        # if post_input.u == 'username' and post_input.p == 'password':
        if validUser:
            # create a session for username and any applicable data to store
            session.username = post_input.u
            session.password = post_input.p
        else:
            session.username = '' 
        # return back to home page
        raise web.seeother('/app')


class logout:
    def GET(self):
        session.username = ''
        raise web.seeother('/app/login')


class cars:
    def GET(self):     
        if not session.username:
            raise web.seeother('/app/login')
        else:  
            # prepare the html
            html = htmlStarter + htmlMainNav + """
        <h1>Cars</h1>
    """

            # get the current cars
            db = web.database(dbn='sqlite', db=appDb)
            allCars = db.select('cars')
            data = '<table>'
            for car in allCars:
                data += '<tr><td>' + str(car.cid) + '. ' + str(car.carname) + '</td></tr>'
            data += '</table>'
            html += data
            addCarForm = """
        <form method='post'>
          <p>add car:</p>
          <p><input name='carname' size='15' maxlength='15'/></p>
          <p><input type='submit' value='add car'/></p>
        </form>
    """    
            html += addCarForm

            return html 

    def POST(self):
        """ process a new car to submit """
        pass


class gasPurchase:
    def GET(self):
        """ add gas purchase to record """         
        if not session.username:
            raise web.seeother('/app/login')
        else:     
            # prepare the html
            html = htmlStarter + htmlMainNav + """
        <h1>Cars</h1>
    """      

            db = web.database(dbn='sqlite', db=appDb)   
            allCars = db.select('cars')

            selectCar = '<select name="carid">'
            for car in allCars:
                selectCar += '<option value="' + str(car.cid) + '">' + str(car.carname) + '</option>'
            selectCar += '</select>'              

            gasPurchases = db.select('gas')
            gasData = "<table class='lined'>"
            gasData += "<tr><th>car ID</th><th>gallons</th><th>odometer</th><th>miles</th><th>vendor</th><th>price per gallon</th><th>bill</th><th>date and time</th></tr>"
            for p in gasPurchases:
                gasData += "<tr><td>" + str(p.car) + "</td><td>" + str(p.gallons) + "</td><td>" +  str(p.odometer) + "</td><td>" +  str(p.milesTraveled) + "</td><td>" +  str(p.vendor) + "</td><td>" +  str(p.ppg) + "</td><td>" +  str(p.bill) + "</td><td>" +  str(p.ts) + "</td></tr>"
            
            gasData += "</table>"

            # set today's date and time for the default timestamp
            from time import localtime, strftime
            tddt = strftime("%Y-%m-%dT%H:%M:%S", localtime())

            # get html gas purchase form going
            addCarForm = """
        <form method='post'>
          <table>
            <tr>
              <th>car:</th>
              <td>""" + selectCar + """</td>
            </tr>   
            <tr>
              <th>miles travelled since last fill-up:</th>
              <td><input name='milesTraveled' size='10' maxlength='10'/></td>
            </tr>
            <tr>
              <th>odometer reading:</th>
              <td><input name='odometer' size='10' maxlength='10'/></td>
            </tr>
            <tr>
              <th>vendor:</th>
              <td><input name='vendor' size='10' maxlength='10'/></td>
            </tr>                  
            <tr>
              <th>gallons:</th>
              <td><input name='gallons' size='10' maxlength='10'/></td>
            </tr>                      
            <tr>
              <th>bill:</th>
              <td><input name='bill' size='10' maxlength='10'/></td>
            </tr>
            <tr>
              <th>price per gallon:</th>
              <td><input name='ppg' size='10' maxlength='10'/></td>
            </tr>
            <tr>
              <th>date filled:</th>
              <td><input name='ts' size='20' value='""" + tddt + """' maxlength='20'/></td>
            </tr>
          </table>
          <p><input type='submit' value='record this purchase'/></p>
        </form>  
    """    
            html += addCarForm + gasData + htmlEnder

            return html    


    def POST(self):              
        if not session.username:
            raise web.seeother('/app/login')
        else:    
            post_input = web.input()
            db = web.database(dbn='sqlite', db=appDb)
            if post_input.bill and post_input.gallons and post_input.odometer and post_input.milesTraveled and post_input.ppg:
                success = db.insert('gas', car=post_input.carid, gallons=post_input.gallons, odometer=post_input.odometer, milesTraveled=post_input.milesTraveled, vendor=post_input.vendor, ppg=post_input.ppg, bill=post_input.bill, ts=post_input.ts)   
                if success:
                    raise web.seeother('/app/cars/gas/purchase')
                else:
                    return "?????"
            else:
                return "the bill, odometer, miles traveled, ppg and gallons inputs must not be empty!"

class environment:
    def GET(self):
        # set up the resource
        environment = web.ctx.env
        resource = "<table>"
        for k in environment.keys():
            resource += "<tr><th style='text-align: right;'>" + k + "</th><td>" + str(environment[k]) + "</td></tr>"
        resource += "</table>"
        return resource

class help:
    def GET(self):
        table = vars(web.ctx)
        resource = "<table>"
        for key, value in table.items():
            if len(value) == 1:
                resource += "<tr><th>" + key + "</th><td>" + value + "</td></tr>"
            else:
                for k,v in value.items():
                    resource += "<tr><th>" + key + "</th><td>" + k + v + "</td></tr>"
        resource += "</table>"    
        return resource

application = app.wsgifunc()
#application = web.application(urls, globals()).wsgifunc()
